/*
 *    Copyright © OpenAtom Foundation.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package com.inspur.edp.formserver.vmmanager.util;

import com.inspur.edp.bef.bizentity.common.BizEntityJsonConst;
import com.inspur.edp.bef.bizentity.pushchangesetargs.ActionChangeDetail;
import com.inspur.edp.bef.bizentity.util.StringUtil;
import com.inspur.edp.das.commonmodel.json.CommonModelNames;
import com.inspur.edp.formserver.viewmodel.GspViewModel;
import com.inspur.edp.formserver.viewmodel.action.IViewModelParameter;
import com.inspur.edp.formserver.viewmodel.action.IViewModelParameterCollection;
import com.inspur.edp.formserver.viewmodel.action.ViewModelAction;
import com.inspur.edp.formserver.viewmodel.action.viewmodelbase.ViewModelParameter;
import com.inspur.edp.formserver.viewmodel.collection.VMActionCollection;
import com.inspur.edp.formserver.viewmodel.common.VMCollectionParameterType;
import com.inspur.edp.formserver.viewmodel.common.VMParameterType;
import com.inspur.edp.lcm.metadata.api.entity.GspMetadata;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class PushActionChangeSet {

  public PushActionChangeSet() {
  }

  /**
   * 根据动作ID获取自定义动作
   * @param metadata
   * @param id
   * @return
   */
  public ViewModelAction getMgrActionByID(GspMetadata metadata,String id) {
    GspViewModel entity = (GspViewModel)metadata.getContent();
    if(entity.getActions() == null | entity.getActions().size() == 0) {
      return null;
    }
    List<ViewModelAction> result = entity.getActions().stream().filter(action ->
        action.getMapping() != null &&
            !StringUtil.checkNull(action.getMapping().getTargetObjId()) &&
            action.getMapping().getTargetObjId().equals(id)).collect(
        Collectors.toList());

    if(result.size() < 1)
      return null;
    return result.get(0);
  }

  /**
   * 新增自定义动作
   * @param metadata
   * @param action
   */
  public void AddMgrAction(GspMetadata metadata, ViewModelAction action) {
    VMActionCollection vmActions = ((GspViewModel)metadata.getContent()).getActions();
    if (vmActions.stream().anyMatch(item -> item.getCode().equals(action.getCode()))) {
      return;
    }
    vmActions.add(action);
  }

  /**
   * 新增动作参数
   * @param orgAction
   * @param refAction
   */
  public void addMgrActionParam(ViewModelAction orgAction, ViewModelAction refAction, String parameterCode) {
      if(refAction.getParameterCollection() == null || refAction.getParameterCollection().size() == 0) {
        return;
      }
      IViewModelParameterCollection orgParams = orgAction.getParameterCollection();

      if(orgParams.stream().anyMatch(item -> ((ViewModelParameter) item).getParamCode().equals(parameterCode))) {
        return;
      }

      refAction.getParameterCollection().forEach(item -> {
        if(((ViewModelParameter) item).getParamCode().equals(parameterCode)) {
          orgAction.getParameterCollection().add(item);
        }
      });
  }


  /**
   * 修改自定义动作
   * @param destAction
   * @param refAction
   * @param changeDetail
   */
  public void ModifyAction(ViewModelAction destAction, ViewModelAction refAction, ActionChangeDetail changeDetail) {
    Map<String, Object> changeInfo = changeDetail.getChangeInfo();
//    String parameterCode = changeDetail.getParameterCode();
    if(destAction == null) {
      return;
    }
    changeInfo.forEach((key,val) -> {
      modifyActionPropertyValue(key, val, destAction, refAction, changeDetail);
    });
  }

  private void modifyActionPropertyValue(String propertyName, Object propertyValue, ViewModelAction destAction, ViewModelAction refAction, ActionChangeDetail changeDetail) {
    if(destAction == null) {
      return;
    }
    String parameterCode = changeDetail.getParameterCode();
    switch (propertyName){
      case CommonModelNames.Code:
        destAction.setCode((String) propertyValue);
        break;
      case BizEntityJsonConst.ReturnValue:
        if(refAction == null) {
          return;
        }
        destAction.setReturnValue(refAction.getReturnValue());
        break;
      case BizEntityJsonConst.CollectionParameterType:
        modifyCollectionParameterType((Integer)propertyValue,destAction,parameterCode);
        break;
      case BizEntityJsonConst.ParamCode:
        modifyParamCode((String)propertyValue,destAction, parameterCode);
        changeDetail.setParameterCode((String)propertyValue);
        break;

      case BizEntityJsonConst.JavaClassName:
        modifyJavaClassName((String)propertyValue,destAction, parameterCode);
        break;

      case BizEntityJsonConst.ParameterType:
        modifyParameterType((Integer)propertyValue,destAction,parameterCode);
        break;
      default:
        throw new RuntimeException(String.format("BE推送自定义动作属性不存在，推送属性为[%1$s]，当前动作编号为[%2$s]，动作名称为[%3$s]",propertyName, destAction.getCode(),destAction.getName()));
    }

  }

  /**
   * 修改动作参数
   * @param newCode
   * @param action
   * @param parameterCode
   */
  private void modifyParamCode(String newCode, ViewModelAction action, String parameterCode){
    for(Object item : action.getParameterCollection()){
      if(((ViewModelParameter)item).getParamCode().equals(parameterCode)) {
        ((IViewModelParameter)item).setParamCode(newCode);
        break;
      }
    }
  }

  /**
   * 修改动作ClassName
   * @param newClassName
   * @param action
   * @param parameterCode
   */
  private void modifyJavaClassName(String newClassName, ViewModelAction action, String parameterCode) {
    for(Object item : action.getParameterCollection()){
      if(((ViewModelParameter)item).getParamCode().equals(parameterCode)) {
        ((IViewModelParameter)item).setClassName(newClassName);
        break;
      }
    }
  }

  /**
   * 修改动作参数类型
   * @param newType
   * @param action
   * @param parameterCode
   */
  private void modifyParameterType(int newType, ViewModelAction action, String parameterCode) {
    for(Object item : action.getParameterCollection()){
      if(((ViewModelParameter)item).getParamCode().equals(parameterCode)) {
        ((IViewModelParameter)item).setParameterType(VMParameterType.forValue(newType));
        break;
      }
    }
  }

  private void modifyCollectionParameterType(int newType, ViewModelAction action, String parameterCode) {
    for(Object item : action.getParameterCollection()) {
      if(((ViewModelParameter)item).getParamCode().equals(parameterCode)) {
        ((IViewModelParameter)item).setCollectionParameterType(VMCollectionParameterType.forValue(newType));
      }
    }
  }

  public void deleteMgrAction(GspMetadata metadata, String actionCode) {
    ((GspViewModel)metadata.getContent()).getActions().removeIf(act ->
      act.getCode().equals(actionCode));
  }

  public void deleteMgrActionPara(ViewModelAction action, String parameterCode) {
    if (action == null || StringUtil.checkNull(parameterCode)) {
      return;
    }
    action.getParameterCollection().removeIf(param -> ((ViewModelParameter)param).getParamCode().equals(parameterCode));
  }

}
